/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux.components;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.UXController;
import jp.ize.ux.UXInteraction;
import jp.ize.ux.UXFocusManager;
import jp.ize.ux.acts.Act;
import jp.ize.ux.components.UXComponent;
import jp.ize.ux.components.UXComponentResource;
import jp.ize.ux.components.themes.basic.UXButtonResource;
import jp.ize.ux.states.UXBasicState;
import jp.ize.ux.interactions.UXGeneralInteraction;
import jp.ize.ux.events.UXMouseEvent;
import jp.ize.ux.events.UXKeyboardEvent;
import jp.ize.ux.geom.UXPoint;
import jp.ize.ux.geom.UXSize;

#if flash9
import flash.ui.Keyboard;
#elseif flash
import flash.Key;
#end
// }}}
// {{{ class UXButtonAct extends Act
/**
 * UXButtonAct クラス<br>
 * UXButtonのデフォルトアクションです。
 */
class UXButtonAct extends Act
{
	// {{{ public function new()
	/**
	 * コンストラクタです。<br>
	 */
	public function new()
	{
		super();
	}
	// }}}
	// {{{ public function normal() : UXButtonState -> Void
	/**
	 * ボタンが実行された時のデフォルトアクションです。
	 */
	public function normal() : UXButtonState -> Void
	{
		return function ( s:UXButtonState ) {
			if ( s.enabled ) {
				if ( s.highlighted ) {
					s.resource.highlighted();
					s.label.textColor = s.label.state.colors.highlight;
				} else if ( s.focused ) {
					s.resource.focused();
					s.label.textColor = s.label.state.colors.focus;
				} else if ( s.selected ) {
					s.resource.setState(UXComponentResource.SELECTED);
					s.label.textColor = s.label.state.colors.select;
				} else {
					s.resource.normal();
					s.label.textColor = s.label.state.colors.normal;
				}
			} else {
				s.resource.disabled();
				s.label.textColor = s.label.state.colors.disable;
			}
		}
	}
	// }}}
	// {{{ public function press() : UXButtonState -> Void
	/**
	 * ボタンが実行された時のデフォルトアクションです。
	 */
	public function press() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.pressed();
			s.label.textColor = s.label.state.colors.press;
		}
	}
	// }}}
	// {{{ public function highlight() : UXButtonState -> Void
	/**
	 * ボタンをハイライトした時のデフォルトアクションです。
	 */
	public function highlight() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.highlighted = true;
			s.resource.highlighted();
			s.label.textColor = s.label.state.colors.highlight;
		}
	}
	// }}}
	// {{{ public function unhighlight() : UXButtonState -> Void
	/**
	 * ボタンをハイライトした時のデフォルトアクションです。
	 */
	public function unhighlight() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.highlighted = false;
			s.resource.normal();
			s.label.textColor = s.label.state.colors.normal;
		}
	}
	// }}}
	// {{{ public function select() : UXButtonState -> Void
	/**
	 * ボタンを選択した時のデフォルトアクションです。
	 */
	public function select() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.setState(UXComponentResource.SELECTED);
			s.label.textColor = s.label.state.colors.select;
		}
	}
	// }}}
	// {{{ public function deselect() : UXButtonState -> Void
	/**
	 * ボタンの選択を解除した時のデフォルトアクションです。
	 */
	public function deselect() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.normal();
			s.label.textColor = s.label.state.colors.normal;
		}
	}
	// }}}
	// {{{ public function focus() : UXButtonState -> Void
	/**
	 * ボタンがフォーカスされた時のデフォルトアクションです。
	 */
	public function focus() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.focused();
			s.label.textColor = s.label.state.colors.focus;
		}
	}
	// }}}
	// {{{ public function unfocus() : UXButtonState -> Void
	/**
	 * ボタンのフォーカスが解除された時のデフォルトアクションです。
	 */
	public function unfocus() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.normal();
			s.label.textColor = s.label.state.colors.normal;
		}
	}
	// }}}
	// {{{ public function enable() : UXButtonState -> Void
	/**
	 * 有効にした時のデフォルトアクションです。
	 */
	public function enable() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.normal();
			s.label.textColor = s.label.state.colors.normal;
		}
	}
	// }}}
	// {{{ public function disable() : UXButtonState -> Void
	/**
	 * 無効にした時のデフォルトアクションです。
	 */
	public function disable() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.disabled();
			s.label.textColor = s.label.state.colors.disable;
		}
	}
	// }}}
	// {{{ public function show() : UXButtonState -> Void
	/**
	 * 表示された時のデフォルトアクションです。
	 */
	public function show() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.visible = true;
		}
	}
	// }}}
	// {{{ public function hide() : UXButtonState -> Void
	/**
	 * 非表示になった時のデフォルトアクションdす。
	 */
	public function hide() : UXButtonState -> Void
	{
		return function( s:UXButtonState ) {
			s.resource.visible = false;
		}
	}
	// }}}
}
// }}}
// {{{ class UXButtonCondition
class UXButtonCondition
{
	// {{{ public var focused(default, default) : Bool
	/**
	 * このボタンにフォーカスが当たっているかどうかを取得、または設定します。
	 */
	public var focused(default, default) : Bool;
	// }}}
	// {{{ public var highlighted(default, default) : Bool
	/**
	 * このボタンがハイライトされているかどうかを取得、または設定します。
	 */
	public var highlighted(default, default) : Bool;
	// }}}
	// {{{ public var selected(default, default) : Bool
	/**
	 * このボタンが選択されているかどうかを取得、または設定します。
	 */
	public var selected(default, default) : Bool;
	// }}}
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
	}

	// }}}
}
// }}}
// {{{ class UXButtonState
/**
 * UXButtonState クラス<br>
 * UXButtonの現在の状態を表すオブジェクトです。
 * UXButtonStateはテキストやアイコンを直線的に配置するため、UXLinearStateを用います。
 */
//class UXButtonState extends UXLinearState
class UXButtonState extends UXBasicState
{
	// {{{ public var resource( default, default ) : UXButtonResource;
	/**
	 * ボタンの描画に使用するリソースです。
	 */
	public var resource( default, default ) : UXComponentResource;
	// }}}
	// {{{ public var label(default, default) : UXLabel
	/**
	 * ボタン上に文字を表示するコンポーネントです。
	 */
	public var label(default, default) : UXLabel;
	// }}}
	// {{{ public var icon( default, default ) : Image;
	/**
	 * ボタン上に画像を表示するアイコンです。デフォルトではnullです。
	 */
	public var icon( default, default ) : UXImage;
	// }}}
	// {{{ public var acts(default, null) : UXButtonAct
	/**
	 * デフォルトのボタンの動きです。
	 */
	public var acts(default, null) : UXButtonAct;
	// }}}
	// {{{ public var focusManager(default, default) : UXFocusManager
	/**
	 * このコンポーネントが属するフォーカスグループの管理オブジェクトです。
	 * このコンポーネントがフォーカスを受け取らない場合はnullです。
	 */
	public var focusManager(default, default) : UXFocusManager;
	// }}}
	// {{{ public function new( ?res:UXComponentResource, ?lbl:UXLabel, ?ico:UXImage, ?color:Int ) : Void
	/**
	 * コンストラクタです。
	 *
	 * @param res: ボタンのリソースです。省略可能です。
	 * @param text: ボタンのUXLabelオブジェクトです。省略可能です。
	 * @param icon: ボタンに表示する画像です。省略可能です。
	 * @param color: リソースを指定しなかった場合の標準ボタンに適用するベース色です。省略可能です。
	 */
	public function new( ?res:UXComponentResource, ?lbl:UXLabel, ?ico:UXImage, ?color:Int ) : Void
	{
		super();
		if ( color==null ) color = 0xAAAAAA;
		if ( lbl==null ) lbl = new UXLabel();
		if ( res==null ) {
			var size = new UXSize(0,0);
			trace(lbl.label.textWidth);
			if ( lbl.label.textWidth<100 ) {
				size.width = 100;
			} else if ( lbl.label.textWidth<200 ) {
				size.width = 200;
			} else if ( lbl.label.textWidth<300 ) {
				size.width = 300;
			} else if ( lbl.label.textWidth>=300 ) {
				size.width = lbl.label.textWidth + 20;
			}
			if ( lbl.label.textHeight<30 ) {
				size.height = 30;
			} else if ( lbl.label.textHeight<40 ) {
				size.height = 40;
			} else if ( lbl.label.textHeight>=40 ) {
				size.height = lbl.label.textHeight + 20;
			}
			res = new UXButtonResource( size, color );
		}
		resource  = res;
		label     = lbl;
		icon      = ico;
		acts       = new UXButtonAct();
		if ( label!=null ) {
			label.label.selectable = false;
		}
		resource.normal();
	}
	// }}}
	// {{{ private function attachResource() : Void
	/**
	 * ボタンに対するグローバルなリソースをresourceプロパティに取得する関数です。
	 */
	private function attachResource() : Void
	{
	}
	// }}}
}
// }}}

// {{{ class UXButton extends UXComponent
/**
 * UXButton クラス<br>
 * ボタンを実現するコンポーネントです。ボタンは一つの背景コンポーネントと複数の前面コンポーネン
 * トがLinearLayoutされているものと定義されています。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id: UXButton.hx 20 2009-02-04 08:23:19Z yimai.v $<br>
 */
class UXButton extends UXComponent<UXButtonState>
{
	// {{{ public function new( ?text:Dynamic="", ?res:UXComponentResource, ?icon:UXImage=null, ?color:Int )
	/**
	 * コンストラクタです。
	 *
	 * @param text: ボタンのテキストです。文字列または、UXLabelのインスタンスが指定可能です。省略可能です。
	 * @param res: ボタンのリソースです。省略可能です。
	 * @param icon: ボタンに表示する画像です。省略可能です。
	 * @param color: リソースを指定しなかった場合の標準ボタンに適用するベース色です。省略可能です。
	 */
	public function new( ?text:Dynamic="", ?res:UXComponentResource, ?icon:UXImage=null, ?color:Int )
	{
		// レイアウトとアクトのインスタンスを作ります。
		if ( text!="" ) {
			var lbl = null; 
			if ( Std.is(text,UXLabel) ) {
				lbl = text;
			} else {
				lbl = new UXLabel(text,12);
			}
			state = new UXButtonState(res,lbl,null,color);
		} else {
			state = new UXButtonState(res,null,null,color);
			state.label.text = text;
		}
		state.target = this;
		state.icon = icon;
		ctrl = new UXController<UXButtonState>( state );
		ctrl.addInteraction( new UXButtonClickInteraction() );
		ctrl.addInteraction( new UXButtonDownInteraction() );
		ctrl.addInteraction( new UXButtonRollOverInteraction() );
		ctrl.addInteraction( new UXButtonRollOutInteraction() );
		ctrl.addInteraction( new UXButtonUpInteraction() );
		super(ctrl);
		if ( icon!=null ) addUXChild(icon);
		if ( res==null ) res = state.resource;
		addUXChild(res);
		var slabel = state.label.label;
		slabel.width  = res.width;
		slabel.height = res.height;
		state.label.x = res.width/2 - slabel.textWidth/2;
		state.label.y = res.height/2 - (slabel.textHeight+2)/2;
		res.addUXChild(state.label);

		ctrl.getInteraction("Click").addReactEvent(UXMouseEvent.CLICK);
		ctrl.getInteraction("Down").addReactEvent(UXMouseEvent.DOWN);
		ctrl.getInteraction("RollOver").addReactEvent(UXMouseEvent.ROLL_OVER);
		ctrl.getInteraction("RollOut").addReactEvent(UXMouseEvent.ROLL_OUT);
		ctrl.getInteraction("Up").addReactEvent(UXMouseEvent.UP);

		ctrl.getInteraction("Down").addAct(state.acts.press());
		ctrl.getInteraction("RollOver").addAct(state.acts.highlight());
		ctrl.getInteraction("RollOut").addAct(state.acts.unhighlight());
		ctrl.getInteraction("Up").addAct(state.acts.normal());
	}
	// }}}
	// {{{ public function refreshResource() : Void
	/**
	 * ボタンに対するグローバルなリソースを再取得する関数です。
	 */
	public function refreshResource() : Void
	{
		state.resource.normal();
	}
	// }}}
	// {{{ public function update( updator : UXButtonState -> Void ) : Void
	/**
	 * このコンポーネントの状態を直接変更するメソッドです。状態のどんな操作も可能になるので、
	 * このメソッドの使用には注意が必要です。
	 */
	public function update( updator : UXButtonState -> Void ) : Void
	{
		updator( state );
	}
	// }}}
	// {{{ public function setEnable( b:Bool ) : Void
	/**
	 * 有効／無効状態を切替えます。
	 */
	public function setEnable( b:Bool ) : Void
	{
		state.enabled = b;
		if ( b ) {
			Act.exec(state.acts.enable(), state);
		} else {
			Act.exec(state.acts.disable(), state);
		}
	}

	// }}}
}
// }}}

// {{{ class UXButtonClickInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonClickInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXButtonClickInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Click");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXButtonDownInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonDownInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXButtonDownInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Down");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXButtonUpInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonUpInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXButtonUpInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Up");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXButtonRollOverInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonRollOverInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXButtonRollOverInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("RollOver");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXButtonRollOutInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonRollOutInteraction クラス<br>
 * ボタンの実行に対するデフォルトインタラクションです。
 */
class UXButtonRollOutInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("RollOut");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
// {{{ class UXButtonSelectInteraction extends UXGeneralInteraction<UXButtonState>
/**
 * UXButtonSelectInteraction クラス<br>
 * ボタンのselect/unselectに対するデフォルトインタラクションです。
 */
class UXButtonSelectInteraction extends UXGeneralInteraction<UXButtonState>
{
	// {{{ public function new() : Void
	/**
	* コンストラクタ
	*/
	public function new() : Void
	{
		super("Select");
		this.judge = function(s) {
			return s.enabled;
		}
	}

	// }}}
}
// }}}
